<template>
  <div class="horizontal-container">
    <div class="doc-det-info">
      <div class="det-head">
        <img src="@/assets/Picture/DocumentManagement/structure.png" alt=" ">
        <div>结构</div>
      </div>
      <div class="det-body">
        <ul>
          <li v-for="(item, index) in paragraphContents" :key="index" class="ellipsis paragraph-item"
            :style="{ marginLeft: item.marginLeft }">
            {{ item.content }}
          </li>
        </ul>
      </div>
    </div>
    <div class="ddc-info">
      <textarea id="editor" v-model="form.content"></textarea>
    </div>
    <!-- 右侧文档信息区域 -->
    <DocumentInfo />
    <div v-if="loading" class="loading-overlay">
      <div class="spinner"></div>
      <div>正在处理，请稍候...</div>
    </div>
  </div>
</template>
<script setup>
import { onMounted, onBeforeUnmount, reactive, ref, watch } from 'vue'
import DocumentInfo from './DocumentInfo.vue'
import { useEditorStore } from '@/store/editor'
import axios from '@/plugins/axios'

// 使用编辑器状态管理
const editorStore = useEditorStore()

const form = reactive({
  content: ''
})

const loading = ref(false)
const paragraphContents = ref([])
// 存储已创建的关系线元素，用于后续清理
const relationLines = ref([])

// 将组件卸载前的保存逻辑替换为直接调用保存函数
onBeforeUnmount(() => {
  const editor = window.tinymce?.get('editor')
  if (editor) {
    // 保存最新内容
    debouncedSaveContent(editor.getContent())
  }
  // 清除关系线
  clearRelationLines()
})
// 添加防抖函数
const debounce = (fn, delay) => {
  let timer = null;
  return function (...args) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};
// 监听编辑器内容变化，直接保存到后端
watch(() => form.content, (newContent) => {
  console.log('[结构标注] 当前编辑器内容:', newContent)
  // 不再使用editorStore.setContent作为主要存储方式
  // 仅用于保存当前状态
  editorStore.setContent(newContent)

  // 直接保存到后端
  // 使用防抖函数包装，避免频繁请求
  debouncedSaveContent(newContent)
})

// 创建防抖后的保存函数
const debouncedSaveContent = debounce((content) => {
  // 从editorStore获取文档ID
  const documentId = editorStore.documentInfo?.id
  console.log('要保存内容到后端的文档id', documentId)
  if (!documentId) {
    console.error('[结构标注] 未找到文档ID，无法保存内容')
    return
  }

  // 发送请求到后端保存内容
  axios.post('/update_document_content', {
    documentId: documentId,
    content: content
  })
    .then(response => {
      if (response.data.code === 200) {
        console.log('[结构标注] 文档内容保存成功')
      } else {
        console.error('[结构标注] 文档内容保存失败:', response.data.message)
      }
    })
    .catch(error => {
      console.error('[结构标注] 保存文档内容请求失败:', error)
    })
}, 1000)

// 动态引入 TinyMCE
const loadTinyMCE = () => {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.src = '/tinymce/tinymce.min.js'
    script.onload = resolve
    script.onerror = reject
    document.head.appendChild(script)
  })
}

// 动态加载LeaderLine库
const loadLeaderLine = () => {
  return new Promise((resolve, reject) => {
    if (window.LeaderLine) {
      resolve(window.LeaderLine);
      return;
    }

    const script = document.createElement('script');
    script.src = 'https://cdn.jsdelivr.net/npm/leader-line@1.0.7/leader-line.min.js';
    script.onload = () => resolve(window.LeaderLine);
    script.onerror = () => reject(new Error('Failed to load LeaderLine'));
    document.head.appendChild(script);
  });
};

// 清除所有关系线
const clearRelationLines = () => {
  // 移除所有关系线
  relationLines.value.forEach(line => {
    if (line.leaderLine) {
      try {
        const lineElement = line.leaderLine.element;
        if (lineElement && lineElement.parentNode) {
          line.leaderLine.remove();
        }
      } catch (error) {
        console.warn('移除关系线时出错:', error);
      }
    }
  });
  relationLines.value = [];
};
// 获取所有可能的关系类型文本
const getRelationTypes = () => {
  // 从localStorage获取关系类定义
  try {
    const storedRelations = localStorage.getItem('relations');
    if (storedRelations) {
      const relations = JSON.parse(storedRelations);
      // 提取所有关系类型的文本
      return relations.map(relation => relation.text || '').filter(text => text);
    }
  } catch (error) {
    console.error('[实体标注] 获取关系类型文本时出错:', error);
  }
  // 默认关系类型列表
  return [];
};
// 清理编辑器内容中可能存在的关系文本标签
const cleanupRelationLabelsInContent = (editor) => {
  if (!editor) return;

  // 获取当前编辑器内容
  const content = editor.getContent();

  // 获取关系类型文本列表
  const relationTypes = getRelationTypes();
  console.log('[结构标注] 关系类型文本列表:', relationTypes);

  if (relationTypes.length === 0) return;

  // 使用DOMParser解析HTML内容
  const parser = new DOMParser();
  const doc = parser.parseFromString(content, 'text/html');

  // 查找所有p标签
  const paragraphs = doc.querySelectorAll('p');
  let hasChanges = false;

  // 遍历所有p标签
  paragraphs.forEach(p => {
    // 检查p标签是否有属性
    if (p.attributes.length === 0 || (p.attributes.length === 1 && p.hasAttribute('data-mce-style'))) {
      const textContent = p.textContent.trim();

      // 检查p标签内容是否完全匹配任何关系类型文本
      const matchesRelationType = relationTypes.some(relationType =>
        textContent === relationType || textContent.includes(relationType)
      );

      // 如果匹配关系类型文本，则删除该p标签
      if (matchesRelationType) {
        p.parentNode.removeChild(p);
        hasChanges = true;
        console.log('[结构标注] 删除了包含关系类型文本的p标签:', textContent);
      }
    }
  });

  // 如果有变化，更新编辑器内容
  if (hasChanges) {
    // 获取修改后的HTML
    const cleanedContent = new XMLSerializer().serializeToString(doc.documentElement);

    // 由于XMLSerializer会包含html和body标签，需要提取实际内容
    const bodyContentMatch = cleanedContent.match(/<body>([\s\S]*?)<\/body>/i);
    const bodyContent = bodyContentMatch ? bodyContentMatch[1] : cleanedContent;

    console.log('[结构标注] 清理了编辑器内容中的关系标签');

    // 使用静默模式设置内容，不触发事件
    // editor.setContent(bodyContent, { no_events: true });

    // 手动更新本地状态
    form.content = bodyContent;
    editorStore.setContent(bodyContent);
    localStorage.setItem('editorContent', bodyContent);

    // 重新提取段落结构，使用节流版本
    setTimeout(() => throttledExtractParagraphs(editor), 10);
  }
};

// 修改drawAllRelations函数，确保关系箭头元素被正确标记
const drawAllRelations = () => {
  // 清除现有关系线
  // clearRelationLines();
  console.log('清除关系线已经结束,开始绘制关系箭头');
  // 确保编辑器实例存在
  const editor = window.tinymce.get('editor');
  if (!editor || !editor.getBody) {
    console.warn('编辑器实例不存在或未完全初始化');
    return;
  }

  // 确保LeaderLine库已加载
  if (typeof window.LeaderLine === 'undefined') {
    console.warn('LeaderLine库未加载，无法绘制关系箭头');
    return;
  }
  const editorBody = editor.getBody();
  if (!editorBody) {
    console.warn('[实体标注] 无法获取编辑器正文元素，无法绘制关系箭头');
    return;
  }

  // 尝试从localStorage获取关系线信息
  let relationLinesInfo = [];
  try {
    const relationLinesInfoStr = localStorage.getItem('relationLinesInfo');
    if (relationLinesInfoStr) {
      relationLinesInfo = JSON.parse(relationLinesInfoStr);
      console.log('[实体标注] 从localStorage获取的关系线信息:', relationLinesInfo.length);
    }
  } catch (error) {
    console.error('[实体标注] 解析关系线信息时出错:', error);
    return; // 如果解析出错，直接返回
  }

  // 如果有关系线信息，优先使用它来绘制关系线
  if (relationLinesInfo && relationLinesInfo.length > 0) {
    // 用于跟踪已绘制的关系，防止重复
    const drawnRelations = new Set();

    // 遍历所有关系线信息
    relationLinesInfo.forEach((lineInfo, index) => {
      try {
        if (!lineInfo || !lineInfo.sourceId || !lineInfo.targetId || !lineInfo.relationId) {
          console.warn(`[实体标注] 关系线信息 ${index} 不完整，跳过`);
          return;
        }

        const sourceId = lineInfo.sourceId;
        const targetId = lineInfo.targetId;
        const relationId = lineInfo.relationId;

        // 创建关系的唯一标识符
        const relationKey = `${sourceId}-${targetId}-${relationId}`;

        // 如果已经绘制过这个完全相同的关系，则跳过
        if (drawnRelations.has(relationKey)) {
          return;
        }

        // 查找源实体和目标实体元素
        const sourceElement = editorBody.querySelector(`span[data-entity-id="${sourceId}"]`);
        const targetElement = editorBody.querySelector(`span[data-entity-id="${targetId}"]`);

        if (!sourceElement || !targetElement) {
          console.warn(`[实体标注] 未找到关系 ${index} 的源实体或目标实体`);
          return;
        }
        // 确保元素在可见范围内并且已经渲染
        if (!isElementVisible(sourceElement) || !isElementVisible(targetElement)) {
          console.warn(`[实体标注] 关系 ${index} 的源实体或目标实体不可见，跳过`);
          return;
        }
        // 检查元素是否在同一个文档中
        if (sourceElement.ownerDocument !== targetElement.ownerDocument) {
          console.warn(`[实体标注] 关系 ${index} 的源实体和目标实体不在同一个文档中，跳过`);
          return;
        }
        // 获取关系类的样式
        const relations = window.relations || [];
        const relationClass = relations.find(r => r.id === relationId);
        const color = lineInfo.color || relationClass?.style?.['background-color'] || '#1890ff';

        // 使用 try-catch 包装 LeaderLine 创建
        try {
          // 创建 LeaderLine 实例 - 使用 window.LeaderLine
          const line = new window.LeaderLine(
            sourceElement,
            targetElement,
            {
              color: color,
              size: 2.5,
              startSocket: lineInfo.startSocket || 'top',
              endSocket: lineInfo.endSocket || 'bottom',
              path: 'grid',
              startSocketGravity: 50,
              endSocketGravity: 50,
              startPlug: 'behind',
              endPlug: 'arrow3',
              endPlugSize: 1.5,
              startPlugColor: color,
              endPlugColor: color,
              animOptions: { duration: 300, timing: 'linear' }
            }
          );

          // 添加关系文本标签
          if (lineInfo.relationText) {
            try {
              line.setOptions({
                middleLabel: window.LeaderLine.captionLabel(lineInfo.relationText, {
                  color: color,
                  fontWeight: 'bold',
                  fontSize: '12px',
                  fontFamily: 'Arial, sans-serif',
                  padding: [4, 8, 4, 8],
                  backgroundColor: 'white',
                  borderRadius: 3,
                  borderWidth: 1.5,
                  borderColor: color
                })
              });
            } catch (labelError) {
              console.error('[实体标注] 设置关系标签时出错:', labelError);
            }
          }

          // 保存关系线信息
          relationLines.value.push({
            id: lineInfo.id || `relation-${sourceId}-${targetId}-${relationId}-${Date.now()}`,
            sourceId: sourceId,
            targetId: targetId,
            relationId: relationId,
            relationText: lineInfo.relationText,
            leaderLine: line
          });

          // 添加标记，确保LeaderLine元素不会被保存
          setTimeout(() => {
            try {
              markLeaderLineElements();
            } catch (error) {
              console.warn('[实体标注] 标记LeaderLine元素时出错:', error);
            }
          }, 500);

          // 标记为已绘制
          drawnRelations.add(relationKey);
        } catch (lineError) {
          console.error(`[实体标注] 创建关系线 ${index} 时出错:`, lineError);
        }
      } catch (error) {
        console.error(`[实体标注] 处理关系线信息 ${index} 时出错:`, error);
      }
    });

    console.log(`[实体标注] 已从关系线信息绘制 ${drawnRelations.size} 个关系箭头`);
    return;
  }
  // 从localStorage获取关系数据
  const relationsData = JSON.parse(localStorage.getItem('relationsData') || '[]');
  if (relationsData.length === 0) {
    console.log('未找到任何关系数据');
    return;
  }

  // 确保window.relations已加载
  if (!window.relations) {
    // 尝试从localStorage加载关系类定义
    try {
      const storedRelations = localStorage.getItem('relations');
      if (storedRelations) {
        window.relations = JSON.parse(storedRelations);
        console.log('从localStorage加载关系类定义:', window.relations.length);
      } else {
        console.warn('未找到关系类定义，箭头将使用默认颜色');
        window.relations = [];
      }
    } catch (error) {
      console.error('加载关系类定义时出错:', error);
      window.relations = [];
    }
  }

  // const editorBody = editor.getBody();
  // 用于跟踪已绘制的关系，防止重复
  const drawnRelations = new Set();

  // 遍历所有关系数据
  relationsData.forEach((relationData, index) => {
    const sourceId = relationData.sourceEntity.id;
    const targetId = relationData.targetEntity.id;
    const relationId = relationData.relation.id;
    const relationText = relationData.relation.text || '';

    // 创建关系的唯一标识符
    const relationKey = `${sourceId}-${targetId}-${relationId}`;

    // 如果已经绘制过这个完全相同的关系，则跳过
    if (drawnRelations.has(relationKey)) {
      console.log(`跳过重复的关系 ${index + 1}:`, sourceId, '->', targetId, relationId);
      return;
    }

    // 查找源实体和目标实体元素
    const sourceElement = editorBody.querySelector(`span[data-entity-id="${sourceId}"]`);
    const targetElement = editorBody.querySelector(`span[data-entity-id="${targetId}"]`);

    if (sourceElement && targetElement) {
      console.log(`找到源实体和目标实体，绘制关系线:`, sourceId, '->', targetId, relationText);

      // 创建一个唯一的ID用于关系线
      const lineId = `relation-${sourceId}-${targetId}-${relationId}-${Date.now()}`;

      // 获取关系类的样式
      const relations = window.relations || [];
      const relationClass = relations.find(r => r.id === relationId);
      const color = relationClass?.style?.['background-color'] || '#1890ff';

      // 确定最佳连接点
      let startSocket = 'top';
      let endSocket = 'bottom';
      const path = 'fluid';

      // 根据元素位置确定最佳连接点
      const sourceRect = sourceElement.getBoundingClientRect();
      const targetRect = targetElement.getBoundingClientRect();

      if (targetRect.top + targetRect.height < sourceRect.top) {
        startSocket = 'top';
        endSocket = 'bottom';
      } else if (targetRect.top > sourceRect.top + sourceRect.height) {
        startSocket = 'bottom';
        endSocket = 'top';
      } else if (targetRect.left + targetRect.width < sourceRect.left) {
        startSocket = 'left';
        endSocket = 'right';
      } else {
        startSocket = 'right';
        endSocket = 'left';
      }

      // 创建LeaderLine实例
      const line = new window.LeaderLine(
        sourceElement,
        targetElement,
        {
          color: color,
          size: 2.5,
          startSocket: startSocket,
          endSocket: endSocket,
          path: path,
          startSocketGravity: 50,
          endSocketGravity: 50,
          startPlug: 'behind',
          endPlug: 'arrow3',
          endPlugSize: 1.5,
          startPlugColor: color,
          endPlugColor: color,
          animOptions: { duration: 300, timing: 'linear' }
        }
      );

      // 添加关系文本标签
      if (relationText) {
        line.setOptions({
          middleLabel: window.LeaderLine.captionLabel(relationText, {
            color: color,
            fontWeight: 'bold',
            fontSize: '12px',
            fontFamily: 'Arial, sans-serif',
            padding: [4, 8, 4, 8],
            backgroundColor: 'white',
            borderRadius: 3,
            borderWidth: 1.5,
            borderColor: color
          })
        });

        if (relationText === '引用') {
          line.setOptions({
            dash: { len: 5, gap: 3 }
          });
        }
      }

      // 保存关系线信息
      relationLines.value.push({
        id: lineId,
        sourceId: sourceId,
        targetId: targetId,
        relationId: relationId,
        relationText: relationText,
        leaderLine: line
      });

      // 添加标记，确保LeaderLine元素不会被保存
      setTimeout(() => {
        try {
          // 使用document.body作为查询范围以确保能找到所有元素
          const allElements = document.body.querySelectorAll('*');
          const leaderLineElements = Array.from(allElements).filter(el => {
            // 更广泛的匹配条件
            return (
              // 匹配SVG元素
              (el.tagName === 'svg' && (
                el.classList.contains('leader-line') ||
                el.style.left || // SVG通常有position样式
                el.getAttribute('viewBox')
              )) ||
              // 匹配任何包含leader-line的ID或类名的元素
              (el.id && el.id.includes('leader-line')) ||
              (el.className && typeof el.className === 'string' && el.className.includes('leader-line')) ||
              // 匹配所有文本标签元素
              (el.tagName === 'text' && el.hasAttribute('x') && el.hasAttribute('y')) ||
              // 匹配路径、使用和标记元素
              (['path', 'use', 'marker', 'mask', 'g'].includes(el.tagName) && el.closest('svg'))
            );
          });

          console.log('找到潜在的LeaderLine元素:', leaderLineElements.length);

          leaderLineElements.forEach(element => {
            element.setAttribute('data-mce-bogus', 'all');
            element.setAttribute('data-leader-line-element', 'true');
            element.style.pointerEvents = 'none';
          });

          console.log(`[实体标注] 已标记 ${leaderLineElements.length} 个 LeaderLine 相关元素`);
        } catch (error) {
          console.warn('[实体标注] 标记LeaderLine元素时出错:', error);
        }
      }, 500);

      // 标记为已绘制
      drawnRelations.add(relationKey);
    } else {
      console.warn(`未找到关系 ${index + 1} 的源实体或目标实体:`,
        sourceElement ? '源实体存在' : '源实体不存在',
        targetElement ? '目标实体存在' : '目标实体不存在');
    }
  });

  console.log(`已绘制 ${drawnRelations.size} 个关系箭头`);
};
// 添加这个辅助函数检查元素是否可见
const isElementVisible = (element) => {
  if (!element || !element.getBoundingClientRect) return false;

  try {
    const rect = element.getBoundingClientRect();
    return rect.width > 0 && rect.height > 0 &&
      element.offsetParent !== null &&
      window.getComputedStyle(element).visibility !== 'hidden';
  } catch (e) {
    console.error('[实体标注] 检查元素可见性时出错:', e);
    return false;
  }
};

// 添加这个辅助函数来标记 LeaderLine 元素
const markLeaderLineElements = () => {
  try {
    // 使用document.body作为查询范围以确保能找到所有元素
    const allElements = document.body.querySelectorAll('*');
    const leaderLineElements = Array.from(allElements).filter(el => {
      try {
        // 更广泛的匹配条件
        return (
          // 匹配SVG元素
          (el.tagName === 'svg' && (
            el.classList.contains('leader-line') ||
            (el.style && el.style.left) || // SVG通常有position样式
            el.getAttribute('viewBox')
          )) ||
          // 匹配任何包含leader-line的ID或类名的元素
          (el.id && el.id.includes('leader-line')) ||
          (el.className && typeof el.className === 'string' && el.className.includes('leader-line')) ||
          // 匹配所有文本标签元素
          (el.tagName === 'text' && el.hasAttribute('x') && el.hasAttribute('y')) ||
          // 匹配路径、使用和标记元素
          (['path', 'use', 'marker', 'mask', 'g'].includes(el.tagName) && el.closest('svg'))
        );
      } catch (elementError) {
        console.warn('[实体标注] 过滤元素时出错:', elementError);
        return false;
      }
    });

    console.log('找到潜在的LeaderLine元素:', leaderLineElements.length);

    leaderLineElements.forEach(element => {
      try {
        element.setAttribute('data-mce-bogus', 'all');
        element.setAttribute('data-leader-line-element', 'true');
        element.style.pointerEvents = 'none';
      } catch (elementError) {
        console.warn('[实体标注] 设置元素属性时出错:', elementError);
      }
    });

    console.log(`[实体标注] 已标记 ${leaderLineElements.length} 个 LeaderLine 相关元素`);
  } catch (error) {
    console.warn('[实体标注] 标记LeaderLine元素时出错:', error);
  }
};
// 提取段落结构函数 - 移到外部以便在整个组件中访问
const extractParagraphs = (editor) => {
  // 添加计时器开始记录执行时间
  console.time('extractParagraphs');

  // 获取当前内容
  const content = editor.getContent();

  // 添加内容哈希检查，避免重复解析相同内容
  const contentHash = hashString(content);
  const lastContentHash = editor._lastContentHash;

  if (contentHash === lastContentHash) {
    console.log('内容未变化，跳过段落提取');
    console.timeEnd('extractParagraphs');
    return;
  }

  // 存储新的哈希值
  editor._lastContentHash = contentHash;

  // 使用更高效的DOM解析方式
  const parser = new DOMParser();
  const doc = parser.parseFromString(content, 'text/html');

  // 提前定义结构类型列表，避免重复查找
  const structureTypes = ['juan', 'pian', 'zhang', 'jie', 'xiaojie'];

  // 使用DocumentFragment来批量操作DOM
  const paragraphs = [];

  // 使用选择器直接过滤有structure-type属性的段落，减少遍历量
  const structuredParagraphs = doc.querySelectorAll('p[structure-type]');

  structuredParagraphs.forEach(el => {
    const textContent = el.textContent.trim();
    const structureType = el.getAttribute('structure-type');

    // 只处理有内容的段落
    if (textContent) {
      const index = structureTypes.indexOf(structureType);
      if (index !== -1) {
        paragraphs.push({
          content: textContent,
          marginLeft: `${index * 20}px`, // 根据索引调整左边距
          type: structureType // 保存结构类型便于快速参考
        });
      }
    }
  });

  // 一次性更新视图，减少重排重绘
  paragraphContents.value = paragraphs;

  // 批量更新到Pinia store
  editorStore.updateStructureAnnotation(paragraphs);

  console.timeEnd('extractParagraphs');
};

// 添加字符串哈希函数，用于检测内容变化
function hashString(str) {
  let hash = 0;
  if (str.length === 0) return hash;
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash = hash & hash; // Convert to 32bit integer
  }
  return hash;
}

// 使用节流函数包装extractParagraphs，避免频繁调用
const throttledExtractParagraphs = throttle(extractParagraphs, 200);

// 节流函数实现
function throttle(func, wait) {
  let timeout = null;
  let previous = 0;

  return function (...args) {
    const now = Date.now();
    const remaining = wait - (now - previous);

    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      func.apply(this, args);
    } else if (!timeout) {
      timeout = setTimeout(() => {
        previous = Date.now();
        timeout = null;
        func.apply(this, args);
      }, remaining);
    }
  };
}

const editorConfig = {
  selector: '#editor', // 选择器，指定哪个元素使用 TinyMCE
  skin_url: '/tinymce/skins/ui/oxide',
  content_css: '/tinymce/tinymce.css', // 自定义内容样式文件路径
  license_key: 'gpl', // 许可密钥，如果是 GPL 版本则不需要设置
  language: 'zh_CN', // 语言设置
  width: '100%', // 编辑器宽度
  height: 650, // 编辑器高度
  statusbar: true, // 是否显示状态栏
  branding: false, // 去除底部的 TinyMCE 广告
  plugins: [
    'searchreplace'
  ], // 启用的插件列表
  toolbar: 'searchreplace copy paste selectall remove |autoPunctuation autoSegment | 卷 篇 章 节 小节 | 注 疏 引 作者 目录',
  paste_as_text: true, // 启用粘贴为纯文本
  toolbar_sticky: true, // 工具栏固定在顶部
  menubar: false, // 隐藏菜单栏
  // 扩展有效元素，确保所有标注类型都能被保留
  extended_valid_elements: 'p[structure-type|class|style],span[data-entity-id|data-checked|data-mce-style|class|style|data-relation-id|data-relation-role|data-relation-target|data-relation-source|data-relation-target-text|data-relation-target-type|var-name]',
  content_style: `
    /* 结构标注样式 */
    p[structure-type="juan"] { font-size: 24px; font-weight: bold; color: #333; }
    p[structure-type="pian"] { font-size: 22px; font-weight: bold; color: #444; }
    p[structure-type="zhang"] { font-size: 20px; font-weight: bold; color: #555; }
    p[structure-type="jie"] { font-size: 18px; font-weight: bold; color: #666; }
    p[structure-type="xiaojie"] { font-size: 16px; font-weight: bold; color: #777; }
    
    /* 实体标注样式 */
    .entity { position: relative; z-index: 10; cursor: pointer !important; }
    span.entity[data-checked="true"] { border: 1px solid #4CAF50; box-shadow: 0 0 2px #4CAF50; }
    span.entity[data-checked="false"] { position: relative; }
    span.entity[data-checked="false"]::after {
      content: "";
      position: absolute;
      top: 0;
      right: 0;
      width: 8px;
      height: 8px;
      background-color: #ff4d4f;
      border-radius: 50%;
      transform: translate(50%, -50%);
      z-index: 100;
      box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
    }
    
    /* 关系标注样式 */
    .entity-arrow-indicator {
      display: inline-block;
      margin: 0 2px;
      font-weight: bold;
      color: blue;
    }
    
    /* 注释、疏、引用等样式 */
    span.zhu { color: #9C27B0; font-style: italic; }
    span.shu { color: #2196F3; text-decoration: underline; }
    span.yin { color: #FF5722; font-weight: bold; }
    span.zuozhe { color: #4CAF50; font-weight: bold; }
    span.mulu { color: #795548; text-decoration: underline; }
  `,
  init_instance_callback: (editor) => {
    // 初始化编辑器后，从editorStore获取内容
    const editorContent = editorStore.getCurrentContent
    console.log('editorContent:', editorContent);
    // 将文档内容放入编辑器中
    editor.setContent(editorContent)
    // 提取段落结构
    throttledExtractParagraphs(editor)
    // 添加更全面的内容变化监听
    editor.on('change NodeChange SetContent ObjectResized input keyup blur', debounce(() => {
      try {
        // 获取当前内容
        const currentContent = editor.getContent()
        // 先清理内容中可能存在的关系文本
        cleanupRelationLabelsInContent(editor)
        console.log('修改后的编辑器内容', currentContent)

        // 更新form内容，触发watch
        form.content = currentContent
        // 保存内容保存到editorStore中，防止刷新得不到最新数据
        editorStore.setContent(currentContent)

        // 提取段落结构
        throttledExtractParagraphs(editor)

        // 内容变化时重新绘制关系箭头
        setTimeout(() => {
          try {
            // 安全清理现有关系线
            if (relationLines.value.length > 0) {
              clearRelationLines()
            }

            // 只有当编辑器是激活的且页面是可见的时才尝试绘制关系线
            if (document.visibilityState === 'visible' && editor.hasFocus()) {
              drawAllRelations()
            }
          } catch (err) {
            console.error('重绘关系线时出错:', err)
          }
        }, 300)
      } catch (err) {
        console.error('编辑器内容变化处理出错:', err)
      }
    }, 1000)) // 使用1秒的防抖，避免频繁保存
    // 加载LeaderLine库并绘制关系箭头
    loadLeaderLine().then(() => {
      console.log('LeaderLine库已加载，开始绘制关系箭头')
      setTimeout(() => {
        drawAllRelations()
      }, 300)
    }).catch(error => {
      console.error('加载LeaderLine库失败:', error)
    })
  },
  setup: (editor) => {
    // 添加这段代码在setup函数的最开始处
    // 添加NodeChange BeforeExecCommand KeyDown事件监听
    editor.on('NodeChange BeforeExecCommand KeyDown', function (e) {
      console.log('TinyMCE Event:', e.type, e);
    });
    const headings = ['卷', '篇', '章', '节', '小节']
    const classes = ['juan', 'pian', 'zhang', 'jie', 'xiaojie']
    // 添加按钮,变化字体大小
    headings.forEach((heading, index) => {
      editor.ui.registry.addButton(heading, {
        text: heading,
        onAction: () => {
          const selectedNode = editor.selection.getNode();
          const paragraphNode = editor.dom.getParent(selectedNode, 'p');

          if (!paragraphNode) {
            // 如果没有找到段落，不执行任何操作
            return;
          }

          const currentType = paragraphNode.getAttribute('structure-type');
          const newType = classes[index];

          if (currentType === newType) {
            // 如果当前类型与新类型相同，则移除类型
            paragraphNode.removeAttribute('structure-type');
          } else {
            // 否则，设置新的 structure-type
            paragraphNode.setAttribute('structure-type', newType);
          }
          // 立即更新结构内容，不等待change事件
          setTimeout(() => throttledExtractParagraphs(editor), 0);
        }
      })
    })
    editor.on('init', () => throttledExtractParagraphs(editor));
    // 注册按钮及其对应的类
    const registerToggleButton = (buttonName, className) => {
      editor.ui.registry.addButton(buttonName, {
        text: buttonName,
        onAction: () => {
          // 获取选中的内容
          const selectedText = editor.selection.getContent({ format: 'text' });

          if (selectedText.trim() === '') {
            return; // 如果没有选中文本，不执行任何操作
          }

          // 获取当前选中的节点
          const selectedNode = editor.selection.getNode();
          // 检查当前选中的是否是已经应用了相同样式的span元素
          if (selectedNode.nodeName === 'SPAN' && selectedNode.classList.contains(className)) {
            // 如果是同样的样式，则移除该样式（用纯文本替换）
            const textContent = selectedNode.textContent;
            editor.dom.remove(selectedNode);
            editor.selection.setContent(textContent);
          } else {
            // 如果不是，则应用新样式
            const range = editor.selection.getRng();
            const span = editor.dom.create('span', { class: className });
            span.innerHTML = selectedText;
            range.deleteContents();
            range.insertNode(span);
            editor.selection.select(span);
          }
        }
      });
    };

    // 注册按钮及其对应的类
    const buttons = [
      { name: '注', class: 'zhu' },
      { name: '疏', class: 'shu' },
      { name: '引', class: 'yin' },
      { name: '作者', class: 'zuozhe' },
      { name: '目录', class: 'mulu' }
    ];

    buttons.forEach(button => {
      registerToggleButton(button.name, button.class);
    });
    // 自动分词和自动标点
    const handleAction = async (action) => {
      const editor = window.tinymce.get('editor');
      if (!editor) {
        console.error('Editor not initialized');
        return;
      }

      const selectedText = editor.selection.getContent({ format: 'text' });
      if (selectedText.trim() === '') {
        return;
      }

      // 显示加载状态
      loading.value = true;

      try {
        let result;
        if (action === 'segment') {
          // 调用分词API
          const response = await axios.post('/cws/getCws', {
            selectedContent: selectedText
          });

          if (response.data && response.data.code === 200) {
            result = response.data.data;
          } else {
            throw new Error('分词请求失败: ' + (response.data?.message || '未知错误'));
          }
        } else if (action === 'punctuate') {
          // 调用自动标点API
          const response = await axios.post('/punc/getSplit', {
            selectedContent: selectedText
          });

          if (response.data && response.data.code === 200) {
            result = response.data.data;
          } else {
            throw new Error('标点请求失败: ' + (response.data?.message || '未知错误'));
          }
        }

        if (result) {
          // 替换编辑器中选中的内容
          editor.selection.setContent(result);
          // 触发内容变化 - 这会自动通过现有的change事件监听器保存内容
          editor.fire('change');
        }
      } catch (error) {
        console.error('处理失败:', error);
        // 可以添加错误提示，如使用Element Plus的ElMessage
        // ElMessage.error(error.message || '处理失败，请稍后重试');
      } finally {
        // 隐藏加载状态
        loading.value = false;
      }
    };

    editor.ui.registry.addButton('autoSegment', {
      icon: 'non-breaking',
      tooltip: '自动分词',
      onAction: () => handleAction('segment')
    });

    editor.ui.registry.addButton('autoPunctuation', {
      icon: 'code-sample',
      tooltip: '自动标点',
      onAction: () => handleAction('punctuate')
    });

    // 在keydown事件处理函数中添加
    editor.on('keydown', function (e) {
      if (e.keyCode === 13) { // 回车键
        const node = editor.selection.getNode();

        // 如果当前在带structure-type的段落内
        if (node.getAttribute('structure-type')) {
          e.preventDefault();

          // 插入一个普通段落
          editor.execCommand('mceInsertContent', false, '</p><p>&nbsp;</p>');
          return false;
        }
      }
    });
  }
};

// 添加DOM观察器，监视编辑器DOM的变化（针对属性变化）
const setupMutationObserver = (editor) => {
  if (!editor || !editor.getBody()) return;

  // 创建DOM变化观察器实例
  const observer = new MutationObserver(debounce((mutations) => {
    // 检查是否有属性变化
    const hasAttributeChanges = mutations.some(mutation =>
      mutation.type === 'attributes' ||
      (mutation.type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0))
    );

    // 如果有属性变化，保存文档
    if (hasAttributeChanges) {
      const currentContent = editor.getContent();
      editorStore.setContent(currentContent);
    }
  }, 1000));

  // 配置观察选项
  const observerConfig = {
    attributes: true, // 观察属性变化
    childList: true, // 观察子节点变化
    subtree: true, // 观察所有后代节点
    attributeOldValue: true // 记录变化前的属性值
  };

  // 开始观察编辑器的DOM
  observer.observe(editor.getBody(), observerConfig);

  // 返回观察器实例，以便后续清理
  return observer;
};

// 在编辑器初始化后设置DOM观察器
let mutationObserver = null;
onMounted(() => {
  // 设置当前标注模式
  editorStore.setAnnotationMode('structure')

  // 确保加载关系类定义
  try {
    const storedRelations = localStorage.getItem('relations')
    if (storedRelations) {
      window.relations = JSON.parse(storedRelations)
      console.log('[结构标注] 从localStorage加载关系类定义:', window.relations.length)
    }
  } catch (error) {
    console.error('[结构标注] 加载关系类定义时出错:', error)
  }
  // 加载tinymce编辑器
  loadTinyMCE()
    .then(() => {
      // 保存编辑器配置到状态管理
      editorStore.setEditorConfig(editorConfig)

      // 初始化编辑器
      window.tinymce.init(editorConfig)

      // 在编辑器初始化后设置观察器
      setTimeout(() => {
        const editor = window.tinymce.get('editor')
        if (editor) {
          mutationObserver = setupMutationObserver(editor)
        }
      }, 1000)
    })
    .catch((error) => {
      console.error('Failed to load TinyMCE:', error) // 处理 TinyMCE 加载失败的情况
    })
})

// 在组件卸载前清理观察器
onBeforeUnmount(() => {
  // 停止DOM观察
  if (mutationObserver) {
    mutationObserver.disconnect()
    mutationObserver = null
  }
})
</script>
<style scoped>
.horizontal-container {
  display: flex;
}

.horizontal-container>div:nth-child(1),
.horizontal-container>div:nth-child(3) {
  flex: 1;
}

.horizontal-container>div:nth-child(2) {
  flex: 3;
}

/*左边样式*/
.doc-det-info {
  margin: 20px;
  width: 240px;
  height: 577px;
  border: #ccc;
  border-radius: 10px;
  padding: 10px 10px 40px;
  background-color: #ffffff;
}

.det-head {
  display: flex;
  justify-content: start;
  align-items: center;
}

.det-head img {
  width: 20px;
  height: 20px;
  object-fit: contain;
  margin-right: 5px;
}

.det-body {
  display: flex;
  justify-content: start;
  align-items: center;
}

/*中间样式*/
.ddc-info {
  width: 100%;
  height: 627px;
  border: 1px solid #ffffff;
  border-radius: 10px;
  background-color: #ffffff;
  margin-right: 10px;
  margin-top: 20px;
  display: flex;
  flex-direction: column;
}

#editor {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.tox-toolbar__primary {
  background-color: #c45656;
}

/*文档信息样式*/
.doc-contain {
  width: 300px;
  height: 580px;
  border: #ccc;
  border-radius: 10px;
  padding: 10px 10px 40px;
  background-color: #ffffff;
  overflow-y: hidden;
  margin-top: 20px;
  margin-right: 20px;
  display: flex;
  flex-direction: column;
  justify-content: start;
  align-items: start;
}

.doc-head {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.doc-head img {
  margin-right: 5px;
}

.doc-body {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: start;
  margin-top: 10px;
}

.doc-info ul {
  list-style-type: none;
  padding: 0;
}

.doc-info li {
  margin-bottom: 0.5rem;
}

.doc-head img {
  height: 20px;
  width: 20px;
  object-fit: contain;
}

.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.spinner {
  border: 4px solid rgba(0, 0, 0, 0.1);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border-left-color: #09f;
  animation: spin 1s ease infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.ellipsis {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 150px;
}

.paragraph-item::before {
  content: '•';
  /* 黑点 */
  font-weight: bold;
  display: inline-block;
  width: 20px;
  /* 调整宽度以居中 */
  text-align: center;
  margin-right: 5px;
  /* 调整与文本的间距 */
}
</style>
